import { defineStore } from 'pinia'
import { ref, reactive, computed } from 'vue'
import router, { routes } from '../../router'
import { loginApi, logoutApi, getUserInfoApi, updateInfoApi, getMenuListApi } from '../../api/user'
import { setRememberInfo } from '@/utils'
// 框架组件
import Layout from '../../layout/index.vue'
// 判断是不是开发环境
const isDev = computed(() => import.meta.env.DEV)

const useUserStore = defineStore('user', () => {
    // 用户id
    const userId = ref('')
    // 用户类型
    const userType = ref('')
    // 用户信息
    const userInfo = reactive({
        roles: [],
        name: '',
        avatar: '',
        introduction: ''
    })
    // token
    const token = ref('')
    // 菜单列表
    const menuList = ref([])
    // 所有的路由组件
    const components = import.meta.glob(`@/views/**/*.vue`, { eager: true })

    // 保存token
    const setToken = val => {
        token.value = val
    }

    // 保存用户id
    const setUserId = id => {
        userId.value = id
    }

    // 保存用户类型 (管理员/学生)
    const setUserType = type => {
        userType.value = type
    }

    // 保存用户信息
    const setUserInfo = info => {
        Object.keys(userInfo).forEach(k => {
            userInfo[k] = info[k]
        })
    }

    // 清空用户信息
    const clearUserInfo = () => {
        userInfo.roles = []
        userInfo.name = ''
        userInfo.avatar = ''
    }

    // 判断用户是否有权限
    const hasRoles = () => {
        return userInfo.roles.length > 0
    }

    // 登录
    const login = async (data) => {
        const res = await loginApi(data)
        if (data.remember) {
            // 保存登录时的账号和密码
            data.code = '' // 不保存验证码
            setRememberInfo(data)
        }
        setToken(res.data.token)
        setUserId(res.data.userId)
        setUserType(res.data.userType)
        // 跳转首页
        router.replace('/')
    }

    // 注销
    const logout = async () => {
        await logoutApi()
        setToken('')
        setUserId('')
        setUserType('')
        clearUserInfo()
        router.replace('/login')
    }

    // 获取用户信息
    const getUserInfo = async () => {
        const res = await getUserInfoApi({
            userId: userId.value,
            userType: userType.value
        })
        // 保存用户信息
        setUserInfo(res.data)
    }

    // 更新用户信息
    const updateUserInfo = async (data) => {
        // 更新用户信息
        const res = await updateInfoApi(data)
        if (res) {
            ElMessage({
                message: res.msg,
                type: 'success'
            })
            // 重新登录
            setTimeout(() => {
                logout()
            }, 200)
        }
    }

    // 判断有没有权限
    const hasPermission = (roles, route) => {
        if (route.meta && route.meta.roles) {
            return roles.some(role => route.meta.roles.includes(role))
        } else {
            return true
        }
    }

    // 递归生成路由
    const filterAsyncRoutes = (routes, roles) => {
        const res = []
        routes.forEach(route => {
            const tmp = { ...route }
            if (hasPermission(roles, tmp)) {
                // 动态生成路由
                const component = tmp.component
                if (component) {
                    if (component === 'Layout') { // 一级路由
                        tmp.component = Layout
                    } else {
                        const componentName = `/src/views${component}.vue`
                        // 动态加载路由组件
                        tmp.component = components[componentName]?.default
                    }
                }
                // 添加子路由
                if (tmp.children) {
                    tmp.children = filterAsyncRoutes(tmp.children, roles)
                }
                res.push(tmp)
            }
        })
        return res
    }

    // 生成对应的动态路由
    const generateRoutes = async () => {
        // 先获取用户信息
        await getUserInfo()
        // 获取菜单信息
        const res = await getMenuListApi({
            userId: userId.value,
            userType: userType.value
        })
        // 生成动态路由
        return filterAsyncRoutes(res.data, userInfo.roles)
    }

    // 保存动态菜单
    const saveMenuList = dyRoutes => {
        menuList.value = [routes[0], ...dyRoutes]
    }

    return {
        token,
        userId,
        userType,
        menuList,
        userInfo,
        saveMenuList,
        hasRoles,
        generateRoutes,
        login,
        updateUserInfo,
        logout
    }
}, {
    persist: true, // 持久化存储
})

export default useUserStore